home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-06-04 | 38.7 KB | 1,070 lines | [TEXT/gamI] |
- ;==============================================================================
-
- ; file: "scheme.scm"
-
- ;------------------------------------------------------------------------------
- ;
- ; Scheme evaluator package:
- ; ------------------------
-
- ; This package contains a Scheme evaluator.
-
- ;------------------------------------------------------------------------------
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (scheme-global-eval expr error)
- (set! scheme-error error)
- (scheme-eval expr))
-
- (define (scheme-eval expr)
- (let ((code (scheme-comp expr scheme-global-environment)))
- (code #f)))
-
- (define scheme-global-environment
- (cons '() ; environment chain
- '())) ; macros
-
- (define (scheme-add-macro name proc)
- (set-cdr! scheme-global-environment
- (cons (cons name proc) (cdr scheme-global-environment)))
- name)
-
- (define scheme-error '())
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define scheme-syntactic-keywords
- (list QUOTE-sym QUASIQUOTE-sym UNQUOTE-sym UNQUOTE-SPLICING-sym
- LAMBDA-sym IF-sym SET!-sym COND-sym =>-sym ELSE-sym AND-sym OR-sym
- CASE-sym LET-sym LET*-sym LETREC-sym BEGIN-sym DO-sym DEFINE-sym
- **DEFINE-MACRO-sym))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (scheme-comp expr env)
-
- (define (push-frame frame env)
- (if (null? frame)
- env
- (cons (cons (car env) frame) (cdr env))))
-
- (define (lookup-var name env)
- (let loop1 ((chain (car env)) (up 0))
- (if (null? chain)
- name
- (let loop2 ((chain chain)
- (up up)
- (frame (cdr chain))
- (over 1))
- (cond ((null? frame)
- (loop1 (car chain) (+ up 1)))
- ((eq? (car frame) name)
- (cons up over))
- (else
- (loop2 chain up (cdr frame) (+ over 1))))))))
-
- (define (macro? name env)
- (assq name (cdr env)))
-
- (define (push-macro name proc env)
- (cons (car env) (cons (cons name proc) (cdr env))))
-
- (define (lookup-macro name env)
- (cdr (assq name (cdr env))))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (variable x)
- (if (not (symbol-object? x))
- (scheme-error "Identifier expected" x))
- (if (memq x scheme-syntactic-keywords)
- (scheme-error "Variable name can not be a syntactic keyword" x)))
-
- (define (shape form n)
- (let loop ((form form) (n n) (l form))
- (cond ((<= n 0))
- ((pair? l)
- (loop form (- n 1) (cdr l)))
- (else
- (scheme-error "Ill-constructed form" form)))))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (macro-expand expr env)
- (apply (lookup-macro (car expr) env) (cdr expr)))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (comp-var expr env)
- (variable expr)
- (gen-var-ref (lookup-var expr env)))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (comp-self-eval expr env)
- (gen-cst expr))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (comp-quote expr env)
- (shape expr 2)
- (gen-cst (cadr expr)))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (comp-quasiquote expr env)
- (comp-quasiquotation (cadr expr) 1 env))
-
- (define (comp-quasiquotation form level env)
- (cond ((= level 0)
- (scheme-comp form env))
- ((pair? form)
- (cond
- ((eq? (car form) QUASIQUOTE-sym)
- (comp-quasiquotation-list form (+ level 1) env))
- ((eq? (car form) UNQUOTE-sym)
- (if (= level 1)
- (scheme-comp (cadr form) env)
- (comp-quasiquotation-list form (- level 1) env)))
- ((eq? (car form) UNQUOTE-SPLICING-sym)
- (if (= level 1)
- (scheme-error "Ill-placed 'unquote-splicing'" form))
- (comp-quasiquotation-list form (- level 1) env))
- (else
- (comp-quasiquotation-list form level env))))
- ((vector? form)
- (gen-vector-form
- (comp-quasiquotation-list (vector->lst form) level env)))
- (else
- (gen-cst form))))
-
- (define (comp-quasiquotation-list l level env)
- (if (pair? l)
- (let ((first (car l)))
- (if (= level 1)
- (if (unquote-splicing? first)
- (begin
- (shape first 2)
- (gen-append-form (scheme-comp (cadr first) env)
- (comp-quasiquotation (cdr l) 1 env)))
- (gen-cons-form (comp-quasiquotation first level env)
- (comp-quasiquotation (cdr l) level env)))
- (gen-cons-form (comp-quasiquotation first level env)
- (comp-quasiquotation (cdr l) level env))))
- (comp-quasiquotation l level env)))
-
- (define (unquote-splicing? x)
- (if (pair? x)
- (if (eq? (car x) UNQUOTE-SPLICING-sym) #t #f)
- #f))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (comp-unquote expr env)
- (scheme-error "Ill-placed 'unquote'" expr))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (comp-unquote-splicing expr env)
- (scheme-error "Ill-placed 'unquote-splicing'" expr))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (comp-set! expr env)
- (shape expr 3)
- (variable (cadr expr))
- (gen-var-set (lookup-var (cadr expr) env) (scheme-comp (caddr expr) env)))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (comp-lambda expr env)
- (shape expr 3)
- (let ((parms (cadr expr)))
- (let ((frame (parms->frame parms)))
- (let ((nb-vars (length frame))
- (code (comp-body (cddr expr) (push-frame frame env))))
- (if (rest-param? parms)
- (gen-lambda-rest nb-vars code)
- (gen-lambda nb-vars code))))))
-
- (define (parms->frame parms)
- (cond ((null? parms)
- '())
- ((pair? parms)
- (let ((x (car parms)))
- (variable x)
- (cons x (parms->frame (cdr parms)))))
- (else
- (variable parms)
- (list parms))))
-
- (define (rest-param? parms)
- (cond ((pair? parms)
- (rest-param? (cdr parms)))
- ((null? parms)
- #f)
- (else
- #t)))
-
- (define (comp-body body env)
-
- (define (letrec-defines vars vals body env)
- (if (pair? body)
-
- (let ((expr (car body)))
- (cond ((not (pair? expr))
- (letrec-defines* vars vals body env))
- ((macro? (car expr) env)
- (letrec-defines vars
- vals
- (cons (macro-expand expr env) (cdr body))
- env))
- (else
- (cond
- ((eq? (car expr) BEGIN-sym)
- (letrec-defines vars
- vals
- (append (cdr expr) (cdr body))
- env))
- ((eq? (car expr) DEFINE-sym)
- (let ((x (definition-name expr)))
- (variable x)
- (letrec-defines (cons x vars)
- (cons (definition-value expr) vals)
- (cdr body)
- env)))
- ((eq? (car expr) **DEFINE-MACRO-sym)
- (let ((x (definition-name expr)))
- (letrec-defines vars
- vals
- (cdr body)
- (push-macro
- x
- (scheme-eval (definition-value expr))
- env))))
- (else
- (letrec-defines* vars vals body env))))))
-
- (scheme-error "Body must contain at least one evaluable expression")))
-
- (define (letrec-defines* vars vals body env)
- (if (null? vars)
- (comp-sequence body env)
- (comp-letrec-aux vars vals body env)))
-
- (letrec-defines '() '() body env))
-
- (define (definition-name expr)
- (shape expr 3)
- (let ((pattern (cadr expr)))
- (let ((name (if (pair? pattern) (car pattern) pattern)))
- (if (not (symbol-object? name))
- (scheme-error "Identifier expected" name))
- name)))
-
- (define (definition-value expr)
- (let ((pattern (cadr expr)))
- (if (pair? pattern)
- (cons LAMBDA-sym (cons (cdr pattern) (cddr expr)))
- (caddr expr))))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (comp-if expr env)
- (shape expr 3)
- (let ((code1 (scheme-comp (cadr expr) env))
- (code2 (scheme-comp (caddr expr) env)))
- (if (pair? (cdddr expr))
- (gen-if code1 code2 (scheme-comp (cadddr expr) env))
- (gen-when code1 code2))))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (comp-cond expr env)
- (comp-cond-aux (cdr expr) env))
-
- (define (comp-cond-aux clauses env)
- (if (pair? clauses)
- (let ((clause (car clauses)))
- (shape clause 1)
- (cond ((eq? (car clause) ELSE-sym)
- (shape clause 2)
- (comp-sequence (cdr clause) env))
- ((not (pair? (cdr clause)))
- (gen-or (scheme-comp (car clause) env)
- (comp-cond-aux (cdr clauses) env)))
- ((eq? (cadr clause) =>-sym)
- (shape clause 3)
- (gen-cond-send (scheme-comp (car clause) env)
- (scheme-comp (caddr clause) env)
- (comp-cond-aux (cdr clauses) env)))
- (else
- (gen-if (scheme-comp (car clause) env)
- (comp-sequence (cdr clause) env)
- (comp-cond-aux (cdr clauses) env)))))
- (gen-cst '())))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (comp-and expr env)
- (let ((rest (cdr expr)))
- (if (pair? rest) (comp-and-aux rest env) (gen-cst #t))))
-
- (define (comp-and-aux l env)
- (let ((code (scheme-comp (car l) env))
- (rest (cdr l)))
- (if (pair? rest) (gen-and code (comp-and-aux rest env)) code)))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (comp-or expr env)
- (let ((rest (cdr expr)))
- (if (pair? rest) (comp-or-aux rest env) (gen-cst #f))))
-
- (define (comp-or-aux l env)
- (let ((code (scheme-comp (car l) env))
- (rest (cdr l)))
- (if (pair? rest) (gen-or code (comp-or-aux rest env)) code)))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (comp-case expr env)
- (shape expr 3)
- (gen-case (scheme-comp (cadr expr) env)
- (comp-case-aux (cddr expr) env)))
-
- (define (comp-case-aux clauses env)
- (if (pair? clauses)
- (let ((clause (car clauses)))
- (shape clause 2)
- (if (eq? (car clause) ELSE-sym)
- (gen-case-else (comp-sequence (cdr clause) env))
- (gen-case-clause (car clause)
- (comp-sequence (cdr clause) env)
- (comp-case-aux (cdr clauses) env))))
- (gen-case-else (gen-cst '()))))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (comp-let expr env)
- (shape expr 3)
- (let ((x (cadr expr)))
- (cond ((symbol-object? x)
- (shape expr 4)
- (let ((y (caddr expr)))
- (let ((proc (cons LAMBDA-sym (cons (bindings->vars y) (cdddr expr)))))
- (scheme-comp (cons (list LETREC-sym (list (list x proc)) x)
- (bindings->vals y))
- env))))
- ((pair? x)
- (scheme-comp (cons (cons LAMBDA-sym (cons (bindings->vars x) (cddr expr)))
- (bindings->vals x))
- env))
- (else
- (comp-body (cddr expr) env)))))
-
- (define (bindings->vars bindings)
- (if (pair? bindings)
- (let ((binding (car bindings)))
- (shape binding 2)
- (let ((x (car binding)))
- (variable x)
- (cons x (bindings->vars (cdr bindings)))))
- '()))
-
- (define (bindings->vals bindings)
- (if (pair? bindings)
- (let ((binding (car bindings)))
- (cons (cadr binding) (bindings->vals (cdr bindings))))
- '()))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (comp-let* expr env)
- (shape expr 3)
- (let ((bindings (cadr expr)))
- (if (pair? bindings)
- (scheme-comp (list LET-sym
- (list (car bindings))
- (cons LET*-sym (cons (cdr bindings) (cddr expr))))
- env)
- (comp-body (cddr expr) env))))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (comp-letrec expr env)
- (shape expr 3)
- (let ((bindings (cadr expr)))
- (comp-letrec-aux (bindings->vars bindings)
- (bindings->vals bindings)
- (cddr expr)
- env)))
-
- (define (comp-letrec-aux vars vals body env)
- (if (pair? vars)
- (let ((new-env (push-frame vars env)))
- (gen-letrec (comp-vals vals new-env)
- (comp-body body new-env)))
- (comp-body body env)))
-
- (define (comp-vals l env)
- (if (pair? l)
- (cons (scheme-comp (car l) env) (comp-vals (cdr l) env))
- '()))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (comp-begin expr env)
- (shape expr 2)
- (comp-sequence (cdr expr) env))
-
- (define (comp-sequence exprs env)
- (if (pair? exprs)
- (comp-sequence-aux exprs env)
- (gen-cst '())))
-
- (define (comp-sequence-aux exprs env)
- (let ((code (scheme-comp (car exprs) env))
- (rest (cdr exprs)))
- (if (pair? rest) (gen-sequence code (comp-sequence-aux rest env)) code)))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (comp-do expr env)
- (shape expr 3)
- (let ((bindings (cadr expr))
- (exit (caddr expr)))
- (shape exit 1)
- (let* ((vars (bindings->vars bindings))
- (new-env1 (push-frame '(#f) env))
- (new-env2 (push-frame vars new-env1)))
- (gen-letrec
- (list
- (gen-lambda
- (length vars)
- (gen-if
- (scheme-comp (car exit) new-env2)
- (comp-sequence (cdr exit) new-env2)
- (gen-sequence
- (comp-sequence (cdddr expr) new-env2)
- (gen-combination
- (gen-var-ref '(1 . 1))
- (comp-vals (bindings->steps bindings) new-env2))))))
- (gen-combination
- (gen-var-ref '(0 . 1))
- (comp-vals (bindings->vals bindings) new-env1))))))
-
- (define (bindings->steps bindings)
- (if (pair? bindings)
- (let ((binding (car bindings)))
- (cons (if (pair? (cddr binding)) (caddr binding) (car binding))
- (bindings->steps (cdr bindings))))
- '()))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (comp-define expr env)
- (shape expr 3)
- (let ((pattern (cadr expr)))
- (let ((x (if (pair? pattern) (car pattern) pattern)))
- (variable x)
- (gen-sequence
- (gen-var-set (lookup-var x env)
- (scheme-comp (if (pair? pattern)
- (cons LAMBDA-sym (cons (cdr pattern) (cddr expr)))
- (caddr expr))
- env))
- (gen-cst x)))))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (comp-define-macro expr env)
- (let ((x (definition-name expr)))
- (gen-macro x (scheme-eval (definition-value expr)))))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (comp-combination expr env)
- (gen-combination (scheme-comp (car expr) env) (comp-vals (cdr expr) env)))
-
- ;------------------------------------------------------------------------------
-
- (define (gen-var-ref var)
- (if (pair? var)
- (gen-rte-ref (car var) (cdr var))
- (gen-glo-ref (scheme-global-var var))))
-
- (define (gen-rte-ref up over)
- (case up
- ((0) (gen-slot-ref-0 over))
- ((1) (gen-slot-ref-1 over))
- (else (gen-slot-ref-up-2 (gen-rte-ref (- up 2) over)))))
-
- (define (gen-slot-ref-0 i)
- (case i
- ((0) (lambda (rte) (vector-ref rte 0)))
- ((1) (lambda (rte) (vector-ref rte 1)))
- ((2) (lambda (rte) (vector-ref rte 2)))
- ((3) (lambda (rte) (vector-ref rte 3)))
- (else (lambda (rte) (vector-ref rte i)))))
-
- (define (gen-slot-ref-1 i)
- (case i
- ((0) (lambda (rte) (vector-ref (vector-ref rte 0) 0)))
- ((1) (lambda (rte) (vector-ref (vector-ref rte 0) 1)))
- ((2) (lambda (rte) (vector-ref (vector-ref rte 0) 2)))
- ((3) (lambda (rte) (vector-ref (vector-ref rte 0) 3)))
- (else (lambda (rte) (vector-ref (vector-ref rte 0) i)))))
-
- (define (gen-slot-ref-up-2 code)
- (lambda (rte) (code (vector-ref (vector-ref rte 0) 0))))
-
- (define (gen-glo-ref i)
- (lambda (rte) (scheme-global-var-ref i)))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (gen-cst val)
- (case val
- ((()) (lambda (rte) '()))
- ((#f) (lambda (rte) #f))
- ((#t) (lambda (rte) #t))
- ((-2) (lambda (rte) -2))
- ((-1) (lambda (rte) -1))
- ((0) (lambda (rte) 0))
- ((1) (lambda (rte) 1))
- ((2) (lambda (rte) 2))
- (else (lambda (rte) val))))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (gen-append-form code1 code2)
- (lambda (rte) (append (code1 rte) (code2 rte))))
-
- (define (gen-cons-form code1 code2)
- (lambda (rte) (cons (code1 rte) (code2 rte))))
-
- (define (gen-vector-form code)
- (lambda (rte) (lst->vector (code rte))))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (gen-var-set var code)
- (if (pair? var)
- (gen-rte-set (car var) (cdr var) code)
- (gen-glo-set (scheme-global-var var) code)))
-
- (define (gen-rte-set up over code)
- (case up
- ((0) (gen-slot-set-0 over code))
- ((1) (gen-slot-set-1 over code))
- (else (gen-slot-set-n (gen-rte-ref (- up 2) 0) over code))))
-
- (define (gen-slot-set-0 i code)
- (case i
- ((0) (lambda (rte) (vector-set! rte 0 (code rte))))
- ((1) (lambda (rte) (vector-set! rte 1 (code rte))))
- ((2) (lambda (rte) (vector-set! rte 2 (code rte))))
- ((3) (lambda (rte) (vector-set! rte 3 (code rte))))
- (else (lambda (rte) (vector-set! rte i (code rte))))))
-
- (define (gen-slot-set-1 i code)
- (case i
- ((0) (lambda (rte) (vector-set! (vector-ref rte 0) 0 (code rte))))
- ((1) (lambda (rte) (vector-set! (vector-ref rte 0) 1 (code rte))))
- ((2) (lambda (rte) (vector-set! (vector-ref rte 0) 2 (code rte))))
- ((3) (lambda (rte) (vector-set! (vector-ref rte 0) 3 (code rte))))
- (else (lambda (rte) (vector-set! (vector-ref rte 0) i (code rte))))))
-
- (define (gen-slot-set-n up i code)
- (case i
- ((0) (lambda (rte) (vector-set! (up (vector-ref rte 0)) 0 (code rte))))
- ((1) (lambda (rte) (vector-set! (up (vector-ref rte 0)) 1 (code rte))))
- ((2) (lambda (rte) (vector-set! (up (vector-ref rte 0)) 2 (code rte))))
- ((3) (lambda (rte) (vector-set! (up (vector-ref rte 0)) 3 (code rte))))
- (else (lambda (rte) (vector-set! (up (vector-ref rte 0)) i (code rte))))))
-
- (define (gen-glo-set i code)
- (lambda (rte) (scheme-global-var-set! i (code rte))))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (gen-lambda-rest nb-vars body)
- (case nb-vars
- ((1) (gen-lambda-1-rest body))
- ((2) (gen-lambda-2-rest body))
- ((3) (gen-lambda-3-rest body))
- (else (gen-lambda-n-rest nb-vars body))))
-
- (define (gen-lambda-1-rest body)
- (lambda (rte)
- (lambda a
- (let ((x (make-vector 2)))
- (vector-set! x 0 rte)
- (vector-set! x 1 a)
- (body x)))))
-
- (define (gen-lambda-2-rest body)
- (lambda (rte)
- (lambda (a . b)
- (let ((x (make-vector 3)))
- (vector-set! x 0 rte)
- (vector-set! x 1 a)
- (vector-set! x 2 b)
- (body x)))))
-
- (define (gen-lambda-3-rest body)
- (lambda (rte)
- (lambda (a b . c)
- (let ((x (make-vector 4)))
- (vector-set! x 0 rte)
- (vector-set! x 1 a)
- (vector-set! x 2 b)
- (vector-set! x 3 c)
- (body x)))))
-
- (define (gen-lambda-n-rest nb-vars body)
- (lambda (rte)
- (lambda (a b c . d)
- (let ((x (make-vector (+ nb-vars 1))))
- (vector-set! x 0 rte)
- (vector-set! x 1 a)
- (vector-set! x 2 b)
- (vector-set! x 3 c)
- (let loop ((n nb-vars) (x x) (i 4) (l d))
- (if (< i n)
- (begin (vector-set! x i (car l)) (loop n x (+ i 1) (cdr l)))
- (vector-set! x i l)))
- (body x)))))
-
- (define (gen-lambda nb-vars body)
- (case nb-vars
- ((0) (gen-lambda-0 body))
- ((1) (gen-lambda-1 body))
- ((2) (gen-lambda-2 body))
- ((3) (gen-lambda-3 body))
- (else (gen-lambda-n nb-vars body))))
-
- (define (gen-lambda-0 body)
- (lambda (rte)
- (lambda ()
- (body rte))))
-
- (define (gen-lambda-1 body)
- (lambda (rte)
- (lambda (a)
- (let ((x (make-vector 2)))
- (vector-set! x 0 rte)
- (vector-set! x 1 a)
- (body x)))))
-
- (define (gen-lambda-2 body)
- (lambda (rte)
- (lambda (a b)
- (let ((x (make-vector 3)))
- (vector-set! x 0 rte)
- (vector-set! x 1 a)
- (vector-set! x 2 b)
- (body x)))))
-
- (define (gen-lambda-3 body)
- (lambda (rte)
- (lambda (a b c)
- (let ((x (make-vector 4)))
- (vector-set! x 0 rte)
- (vector-set! x 1 a)
- (vector-set! x 2 b)
- (vector-set! x 3 c)
- (body x)))))
-
- (define (gen-lambda-n nb-vars body)
- (lambda (rte)
- (lambda (a b c . d)
- (let ((x (make-vector (+ nb-vars 1))))
- (vector-set! x 0 rte)
- (vector-set! x 1 a)
- (vector-set! x 2 b)
- (vector-set! x 3 c)
- (let loop ((n nb-vars) (x x) (i 4) (l d))
- (if (<= i n)
- (begin (vector-set! x i (car l)) (loop n x (+ i 1) (cdr l)))))
- (body x)))))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (gen-sequence code1 code2)
- (lambda (rte) (code1 rte) (code2 rte)))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (gen-when code1 code2)
- (lambda (rte)
- (let ((temp (code1 rte)))
- (if (false-object? temp)
- '()
- (code2 rte)))))
-
- (define (gen-if code1 code2 code3)
- (lambda (rte)
- (let ((temp (code1 rte)))
- (if (false-object? temp)
- (code3 rte)
- (code2 rte)))))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (gen-cond-send code1 code2 code3)
- (lambda (rte)
- (let ((temp (code1 rte)))
- (if (false-object? temp)
- (code3 rte)
- ((code2 rte) temp)))))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (gen-and code1 code2)
- (lambda (rte)
- (let ((temp (code1 rte)))
- (if (false-object? temp)
- temp
- (code2 rte)))))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (gen-or code1 code2)
- (lambda (rte)
- (let ((temp (code1 rte)))
- (if (false-object? temp)
- (code2 rte)
- temp))))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (gen-case code1 code2)
- (lambda (rte) (code2 rte (code1 rte))))
-
- (define (gen-case-clause datums code1 code2)
- (lambda (rte key) (if (memv key datums) (code1 rte) (code2 rte key))))
-
- (define (gen-case-else code)
- (lambda (rte key) (code rte)))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (gen-letrec vals body)
- (let ((nb-vals (length vals)))
- (case nb-vals
- ((1) (gen-letrec-1 (car vals) body))
- ((2) (gen-letrec-2 (car vals) (cadr vals) body))
- ((3) (gen-letrec-3 (car vals) (cadr vals) (caddr vals) body))
- (else (gen-letrec-n nb-vals vals body)))))
-
- (define (gen-letrec-1 val1 body)
- (lambda (rte)
- (let ((x (make-vector 2)))
- (vector-set! x 0 rte)
- (vector-set! x 1 (val1 x))
- (body x))))
-
- (define (gen-letrec-2 val1 val2 body)
- (lambda (rte)
- (let ((x (make-vector 3)))
- (vector-set! x 0 rte)
- (vector-set! x 1 (val1 x))
- (vector-set! x 2 (val2 x))
- (body x))))
-
- (define (gen-letrec-3 val1 val2 val3 body)
- (lambda (rte)
- (let ((x (make-vector 4)))
- (vector-set! x 0 rte)
- (vector-set! x 1 (val1 x))
- (vector-set! x 2 (val2 x))
- (vector-set! x 3 (val3 x))
- (body x))))
-
- (define (gen-letrec-n nb-vals vals body)
- (lambda (rte)
- (let ((x (make-vector (+ nb-vals 1))))
- (vector-set! x 0 rte)
- (let loop ((x x) (i 1) (l vals))
- (if (pair? l)
- (begin (vector-set! x i ((car l) x)) (loop x (+ i 1) (cdr l)))))
- (body x))))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (gen-macro name proc)
- (lambda (rte) (scheme-add-macro name proc)))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (gen-combination oper args)
- (case (length args)
- ((0) (gen-combination-0 oper))
- ((1) (gen-combination-1 oper (car args)))
- ((2) (gen-combination-2 oper (car args) (cadr args)))
- ((3) (gen-combination-3 oper (car args) (cadr args) (caddr args)))
- (else (gen-combination-n oper args))))
-
- (define (gen-combination-0 oper)
- (lambda (rte) ((oper rte))))
-
- (define (gen-combination-1 oper arg1)
- (lambda (rte) ((oper rte) (arg1 rte))))
-
- (define (gen-combination-2 oper arg1 arg2)
- (lambda (rte) ((oper rte) (arg1 rte) (arg2 rte))))
-
- (define (gen-combination-3 oper arg1 arg2 arg3)
- (lambda (rte) ((oper rte) (arg1 rte) (arg2 rte) (arg3 rte))))
-
- (define (gen-combination-n oper args)
- (lambda (rte)
- (define (evaluate l rte)
- (if (pair? l)
- (cons ((car l) rte) (evaluate (cdr l) rte))
- '()))
- (apply (oper rte) (evaluate args rte))))
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (cond ((symbol-object? expr)
- (comp-var expr env))
- ((not (pair? expr))
- (comp-self-eval expr env))
- ((macro? (car expr) env)
- (scheme-comp (macro-expand expr env) env))
- (else
- (cond
- ((eq? (car expr) QUOTE-sym) (comp-quote expr env))
- ((eq? (car expr) QUASIQUOTE-sym) (comp-quasiquote expr env))
- ((eq? (car expr) UNQUOTE-sym) (comp-unquote expr env))
- ((eq? (car expr) UNQUOTE-SPLICING-sym) (comp-unquote-splicing expr env))
- ((eq? (car expr) SET!-sym) (comp-set! expr env))
- ((eq? (car expr) LAMBDA-sym) (comp-lambda expr env))
- ((eq? (car expr) IF-sym) (comp-if expr env))
- ((eq? (car expr) COND-sym) (comp-cond expr env))
- ((eq? (car expr) AND-sym) (comp-and expr env))
- ((eq? (car expr) OR-sym) (comp-or expr env))
- ((eq? (car expr) CASE-sym) (comp-case expr env))
- ((eq? (car expr) LET-sym) (comp-let expr env))
- ((eq? (car expr) LET*-sym) (comp-let* expr env))
- ((eq? (car expr) LETREC-sym) (comp-letrec expr env))
- ((eq? (car expr) BEGIN-sym) (comp-begin expr env))
- ((eq? (car expr) DO-sym) (comp-do expr env))
- ((eq? (car expr) DEFINE-sym) (comp-define expr env))
- ((eq? (car expr) **DEFINE-MACRO-sym) (comp-define-macro expr env))
- (else (comp-combination expr env)))))
-
- )
-
- ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- (define (scheme-global-var name)
- (let ((x (assq name scheme-global-variables)))
- (if x
- x
- (let ((y (cons name '())))
- (set! scheme-global-variables (cons y scheme-global-variables))
- y))))
-
- (define (scheme-global-var-ref i)
- (cdr i))
-
- (define (scheme-global-var-set! i val)
- (set-cdr! i val)
- '())
-
- (define scheme-global-variables '())
-
- (define (scheme-norm-proc name value)
- (scheme-global-var-set!
- (scheme-global-var (string->canonical-symbol name))
- value))
-
- (define (scheme-bool-proc name value)
- (scheme-norm-proc name
- (lambda l (let ((x (apply value l))) (if x #t false-object)))))
-
- (scheme-bool-proc "NOT" (lambda (x) (false-object? x)))
- (scheme-bool-proc "BOOLEAN?" (lambda (x) (or (eq? x #t) (false-object? x))))
- (scheme-bool-proc "EQV?" EQV?)
- (scheme-bool-proc "EQ?" EQ?)
- (scheme-bool-proc "EQUAL?" EQUAL?)
- (scheme-bool-proc "PAIR?" PAIR?)
- (scheme-norm-proc "CONS" CONS)
- (scheme-norm-proc "CAR" CAR)
- (scheme-norm-proc "CDR" CDR)
- (scheme-norm-proc "SET-CAR!" SET-CAR!)
- (scheme-norm-proc "SET-CDR!" SET-CDR!)
- (scheme-norm-proc "CAAR" CAAR)
- (scheme-norm-proc "CADR" CADR)
- (scheme-norm-proc "CDAR" CDAR)
- (scheme-norm-proc "CDDR" CDDR)
- (scheme-norm-proc "CAAAR" CAAAR)
- (scheme-norm-proc "CAADR" CAADR)
- (scheme-norm-proc "CADAR" CADAR)
- (scheme-norm-proc "CADDR" CADDR)
- (scheme-norm-proc "CDAAR" CDAAR)
- (scheme-norm-proc "CDADR" CDADR)
- (scheme-norm-proc "CDDAR" CDDAR)
- (scheme-norm-proc "CDDDR" CDDDR)
- (scheme-norm-proc "CAAAAR" CAAAAR)
- (scheme-norm-proc "CAAADR" CAAADR)
- (scheme-norm-proc "CAADAR" CAADAR)
- (scheme-norm-proc "CAADDR" CAADDR)
- (scheme-norm-proc "CADAAR" CADAAR)
- (scheme-norm-proc "CADADR" CADADR)
- (scheme-norm-proc "CADDAR" CADDAR)
- (scheme-norm-proc "CADDDR" CADDDR)
- (scheme-norm-proc "CDAAAR" CDAAAR)
- (scheme-norm-proc "CDAADR" CDAADR)
- (scheme-norm-proc "CDADAR" CDADAR)
- (scheme-norm-proc "CDADDR" CDADDR)
- (scheme-norm-proc "CDDAAR" CDDAAR)
- (scheme-norm-proc "CDDADR" CDDADR)
- (scheme-norm-proc "CDDDAR" CDDDAR)
- (scheme-norm-proc "CDDDDR" CDDDDR)
- (scheme-bool-proc "NULL?" NULL?)
- (scheme-bool-proc "LIST?" LIST?)
- (scheme-norm-proc "LIST" LIST)
- (scheme-norm-proc "LENGTH" LENGTH)
- (scheme-norm-proc "APPEND" APPEND)
- (scheme-norm-proc "REVERSE" REVERSE)
- (scheme-norm-proc "LIST-REF" LIST-REF)
- (scheme-bool-proc "MEMQ" MEMQ)
- (scheme-bool-proc "MEMV" MEMV)
- (scheme-bool-proc "MEMBER" MEMBER)
- (scheme-bool-proc "ASSQ" ASSQ)
- (scheme-bool-proc "ASSV" ASSV)
- (scheme-bool-proc "ASSOC" ASSOC)
- (scheme-bool-proc "SYMBOL?" (lambda (x) (symbol-object? x)))
- (scheme-norm-proc "SYMBOL->STRING" SYMBOL->STRING)
- (scheme-norm-proc "STRING->SYMBOL" STRING->SYMBOL)
- (scheme-bool-proc "NUMBER?" NUMBER?)
- (scheme-bool-proc "COMPLEX?" COMPLEX?)
- (scheme-bool-proc "REAL?" REAL?)
- (scheme-bool-proc "RATIONAL?" RATIONAL?)
- (scheme-bool-proc "INTEGER?" INTEGER?)
- (scheme-bool-proc "EXACT?" EXACT?)
- (scheme-bool-proc "INEXACT?" INEXACT?)
- (scheme-bool-proc "=" =)
- (scheme-bool-proc "<" <)
- (scheme-bool-proc ">" >)
- (scheme-bool-proc "<=" <=)
- (scheme-bool-proc ">=" >=)
- (scheme-bool-proc "ZERO?" ZERO?)
- (scheme-bool-proc "POSITIVE?" POSITIVE?)
- (scheme-bool-proc "NEGATIVE?" NEGATIVE?)
- (scheme-bool-proc "ODD?" ODD?)
- (scheme-bool-proc "EVEN?" EVEN?)
- (scheme-norm-proc "MAX" MAX)
- (scheme-norm-proc "MIN" MIN)
- (scheme-norm-proc "+" +)
- (scheme-norm-proc "*" *)
- (scheme-norm-proc "-" -)
- (scheme-norm-proc "/" /)
- (scheme-norm-proc "ABS" ABS)
- (scheme-norm-proc "QUOTIENT" QUOTIENT)
- (scheme-norm-proc "REMAINDER" REMAINDER)
- (scheme-norm-proc "MODULO" MODULO)
- (scheme-norm-proc "GCD" GCD)
- (scheme-norm-proc "LCM" LCM)
- (scheme-norm-proc "NUMERATOR" NUMERATOR)
- (scheme-norm-proc "DENOMINATOR" DENOMINATOR)
- (scheme-norm-proc "FLOOR" FLOOR)
- (scheme-norm-proc "CEILING" CEILING)
- (scheme-norm-proc "TRUNCATE" TRUNCATE)
- (scheme-norm-proc "ROUND" ROUND)
- (scheme-norm-proc "RATIONALIZE" RATIONALIZE)
- (scheme-norm-proc "EXP" EXP)
- (scheme-norm-proc "LOG" LOG)
- (scheme-norm-proc "SIN" SIN)
- (scheme-norm-proc "COS" COS)
- (scheme-norm-proc "TAN" TAN)
- (scheme-norm-proc "ASIN" ASIN)
- (scheme-norm-proc "ACOS" ACOS)
- (scheme-norm-proc "ATAN" ATAN)
- (scheme-norm-proc "SQRT" SQRT)
- (scheme-norm-proc "EXPT" EXPT)
- (scheme-norm-proc "MAKE-RECTANGULAR" MAKE-RECTANGULAR)
- (scheme-norm-proc "MAKE-POLAR" MAKE-POLAR)
- (scheme-norm-proc "REAL-PART" REAL-PART)
- (scheme-norm-proc "IMAG-PART" IMAG-PART)
- (scheme-norm-proc "MAGNITUDE" MAGNITUDE)
- (scheme-norm-proc "ANGLE" ANGLE)
- (scheme-norm-proc "EXACT->INEXACT" EXACT->INEXACT)
- (scheme-norm-proc "INEXACT->EXACT" INEXACT->EXACT)
- (scheme-norm-proc "NUMBER->STRING" NUMBER->STRING)
- (scheme-norm-proc "STRING->NUMBER" STRING->NUMBER)
- (scheme-bool-proc "CHAR?" CHAR?)
- (scheme-bool-proc "CHAR=?" CHAR=?)
- (scheme-bool-proc "CHAR<?" CHAR<?)
- (scheme-bool-proc "CHAR>?" CHAR>?)
- (scheme-bool-proc "CHAR<=?" CHAR<=?)
- (scheme-bool-proc "CHAR>=?" CHAR>=?)
- (scheme-bool-proc "CHAR-CI=?" CHAR-CI=?)
- (scheme-bool-proc "CHAR-CI<?" CHAR-CI<?)
- (scheme-bool-proc "CHAR-CI>?" CHAR-CI>?)
- (scheme-bool-proc "CHAR-CI<=?" CHAR-CI<=?)
- (scheme-bool-proc "CHAR-CI>=?" CHAR-CI>=?)
- (scheme-bool-proc "CHAR-ALPHABETIC?" CHAR-ALPHABETIC?)
- (scheme-bool-proc "CHAR-NUMERIC?" CHAR-NUMERIC?)
- (scheme-bool-proc "CHAR-WHITESPACE?" CHAR-WHITESPACE?)
- (scheme-bool-proc "CHAR-LOWER-CASE?" CHAR-LOWER-CASE?)
- (scheme-norm-proc "CHAR->INTEGER" CHAR->INTEGER)
- (scheme-norm-proc "INTEGER->CHAR" INTEGER->CHAR)
- (scheme-norm-proc "CHAR-UPCASE" CHAR-UPCASE)
- (scheme-norm-proc "CHAR-DOWNCASE" CHAR-DOWNCASE)
- (scheme-bool-proc "STRING?" STRING?)
- (scheme-norm-proc "MAKE-STRING" MAKE-STRING)
- (scheme-norm-proc "STRING" STRING)
- (scheme-norm-proc "STRING-LENGTH" STRING-LENGTH)
- (scheme-norm-proc "STRING-REF" STRING-REF)
- (scheme-norm-proc "STRING-SET!" STRING-SET!)
- (scheme-bool-proc "STRING=?" STRING=?)
- (scheme-bool-proc "STRING<?" STRING<?)
- (scheme-bool-proc "STRING>?" STRING>?)
- (scheme-bool-proc "STRING<=?" STRING<=?)
- (scheme-bool-proc "STRING>=?" STRING>=?)
- (scheme-bool-proc "STRING-CI=?" STRING-CI=?)
- (scheme-bool-proc "STRING-CI<?" STRING-CI<?)
- (scheme-bool-proc "STRING-CI>?" STRING-CI>?)
- (scheme-bool-proc "STRING-CI<=?" STRING-CI<=?)
- (scheme-bool-proc "STRING-CI>=?" STRING-CI>=?)
- (scheme-norm-proc "SUBSTRING" SUBSTRING)
- (scheme-norm-proc "STRING-APPEND" STRING-APPEND)
- (scheme-bool-proc "VECTOR?" VECTOR?)
- (scheme-norm-proc "MAKE-VECTOR" MAKE-VECTOR)
- (scheme-norm-proc "VECTOR" VECTOR)
- (scheme-norm-proc "VECTOR-LENGTH" VECTOR-LENGTH)
- (scheme-norm-proc "VECTOR-REF" VECTOR-REF)
- (scheme-norm-proc "VECTOR-SET!" VECTOR-SET!)
- (scheme-bool-proc "PROCEDURE?" PROCEDURE?)
- (scheme-norm-proc "APPLY" APPLY)
- (scheme-norm-proc "MAP" MAP)
- (scheme-norm-proc "FOR-EACH" FOR-EACH)
- (scheme-norm-proc "CALL-WITH-CURRENT-CONTINUATION" CALL-WITH-CURRENT-CONTINUATION)
- (scheme-norm-proc "CALL-WITH-INPUT-FILE" CALL-WITH-INPUT-FILE)
- (scheme-norm-proc "CALL-WITH-OUTPUT-FILE" CALL-WITH-OUTPUT-FILE)
- (scheme-bool-proc "INPUT-PORT?" INPUT-PORT?)
- (scheme-bool-proc "OUTPUT-PORT?" OUTPUT-PORT?)
- (scheme-norm-proc "CURRENT-INPUT-PORT" CURRENT-INPUT-PORT)
- (scheme-norm-proc "CURRENT-OUTPUT-PORT" CURRENT-OUTPUT-PORT)
- (scheme-norm-proc "OPEN-INPUT-FILE" OPEN-INPUT-FILE)
- (scheme-norm-proc "OPEN-OUTPUT-FILE" OPEN-OUTPUT-FILE)
- (scheme-norm-proc "CLOSE-INPUT-PORT" CLOSE-INPUT-PORT)
- (scheme-norm-proc "CLOSE-OUTPUT-PORT" CLOSE-OUTPUT-PORT)
- (scheme-bool-proc "EOF-OBJECT?" EOF-OBJECT?)
- (scheme-norm-proc "READ" READ)
- (scheme-norm-proc "READ-CHAR" READ-CHAR)
- (scheme-norm-proc "PEEK-CHAR" PEEK-CHAR)
- (scheme-norm-proc "WRITE" WRITE)
- (scheme-norm-proc "DISPLAY" DISPLAY)
- (scheme-norm-proc "NEWLINE" NEWLINE)
- (scheme-norm-proc "WRITE-CHAR" WRITE-CHAR)
-
- ;==============================================================================
-